/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine - graphics/renderer
// Copyright (c) 2015.  All Rights Reserved
//
// File:		AESimpleRenderState.h
// Author:		Gianluca Belardelli
// Date:		10/02/2015
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AESIMPLERENDERSTATE_H_
#define _AESIMPLERENDERSTATE_H_

// flags for simple render state flags
#define AERENDERSTATEFLAG_NONE                0x00000000
#define AERENDERSTATEFLAG_FRONTFACE           0x00000001
#define AERENDERSTATEFLAG_BACKFACE            0x00000002
#define AERENDERSTATEFLAG_DOUBLESIDED         (AERENDERSTATEFLAG_FRONTFACE|AERENDERSTATEFLAG_BACKFACE)
#define AERENDERSTATEFLAG_ALWAYSVISIBLE       0x00000004
#define AERENDERSTATEFLAG_WRITETOZBUFFER      0x00000008
#define AERENDERSTATEFLAG_ALPHATEST           0x00000010
#define AERENDERSTATEFLAG_USEFOG              0x00000020
#define AERENDERSTATEFLAG_LUMINANCETOALPHA    0x00000040
#define AERENDERSTATEFLAG_FILTERING           0x00000080
#define AERENDERSTATEFLAG_USEADDITIVEALPHA    0x00000100
#define AERENDERSTATEFLAG_SAMPLERCLAMPING     0x00000200
#define AERENDERSTATEFLAG_NOWIREFRAME         0x00000400
#define AERENDERSTATEFLAG_USESCISSORTEST      0x00000800
#define AERENDERSTATEFLAG_NOMULTISAMPLING     0x00001000
#define AERENDERSTATEFLAG_CUSTOMBIT           0x00008000

// helper flag combination that can be used when passed to IVRenderInterface::DrawLine
#define AERENDERSTATEFLAG_LINE2D           (AERENDERSTATEFLAG_FRONTFACE|AERENDERSTATEFLAG_ALWAYSVISIBLE|AERENDERSTATEFLAG_CUSTOMBIT)

#define AERENDERSTATE_UNDEFINED   -1


/// \brief
///   A structure that defines a simple render state packed into a 32bit value
/// 
/// Only a small subset of render states is supported by this structure (e.g. alpha blending, backface culling, depth test/depth write,
/// texture clamping, scissoring).
/// 
/// This simple render state is typically used for rendering less complex geometry batches such as
/// 2D overlays.
struct AESimpleRenderState
{
// Members
public:
	// data:
	union
	{
		struct
		{
			AEUINT8 nTranspMode;
			AEUINT8 nUnused;
			AEUINT16 nRenderFlags;
		};
		AEINT32 nAllProperties;
	};	

// Methods
public:
	/// \brief
	///   Empty constructor. Sets defaults
	AE_FORCEINLINE AESimpleRenderState( void );
	
	/// \brief
	///   Constructor that takes the transparency type and state flags.
	/// 
	/// \param nTransp
	///   One of the blending modes defined in VIS_TransparencyType.
	/// 
	/// \param nFlags
	///   bitflags; the following flags are supported:
	///   \li AERENDERSTATEFLAG_FRONTFACE: The front faces are rendered (default).
	/// 
	///   \li AERENDERSTATEFLAG_BACKFACE: The back faces are rendered.
	/// 
	///   \li AERENDERSTATEFLAG_DOUBLESIDED: doublesided; combination of AERENDERSTATEFLAG_FRONTFACE and
	///     AERENDERSTATEFLAG_BACKFACE bit.
	/// 
	///   \li AERENDERSTATEFLAG_ALWAYSVISIBLE: No z-test is performed while rendering.
	/// 
	///   \li AERENDERSTATEFLAG_WRITETOZBUFFER: Rasterizer writes to z-buffer.
	/// 
	///   \li AERENDERSTATEFLAG_ALPHATEST: Alpha test is performed using the global alpha threshold
	///     value. Only supported on platforms supporting the alpha test state (Windows DirectX9, Playstation 3, Xbox360).
	/// 
	///   \li AERENDERSTATEFLAG_LUMINANCETOALPHA: Used for fonts that need to copy the luminance value
	///     into the alpha channel.
	/// 
	///   \li AERENDERSTATEFLAG_FILTERING: Bilinear filtering is enabled on the used sampler(s) (otherwise just point
	///     sampling).
	/// 
	///   \li AERENDERSTATEFLAG_USEADDITIVEALPHA: Determines whether additive blending multiplies the
	///     source color with source alpha.
	/// 
	///   \li AERENDERSTATEFLAG_SAMPLERCLAMPING: If enabled, used sampler(s) use clamping
	/// 
	///   \li AERENDERSTATEFLAG_NOWIREFRAME: Ignores the global wireframe mode (e.g. fonts should be
	///     displayed correctly also in wireframe mode).
	/// 
	///   \li AERENDERSTATEFLAG_USESCISSORTEST: Enable scissor test.
	/// 
	///   \li AERENDERSTATEFLAG_CUSTOMBIT: For custom usage (ignored by Vision).
	AE_FORCEINLINE AESimpleRenderState( AEINT32 nTransp, AEINT32 nFlags=AERENDERSTATEFLAG_FRONTFACE );
	
	/// \brief
	///   Invalidates the simple render state to -1
	AE_FORCEINLINE void Invalidate( void );
	
	/// \brief
	///   Sets the blending mode, must be one of the values in VIS_TransparencyType.
	AE_FORCEINLINE void SetTransparency( AEINT32 nTransp );
	
	/// \brief
	///   Returns the blending mode, must be one of the values in VIS_TransparencyType.
	AE_FORCEINLINE AEINT32 GetTransparency( void ) const;
	
	/// \brief
	///   Translates the AECullMode value to the face culling bitflags and sets them in the simple render state object.
	AE_FORCEINLINE void SetFaceCullMode( AECullMode nMode );
	
	/// \brief
	///   Translates the face culling bitflags into a AECullMode enum value and returns the result.
	AE_FORCEINLINE AECullMode GetFaceCullMode( void ) const;
	
	/// \brief
	///   Sets all bitflags (see constructor for supported bitflags)
	AE_FORCEINLINE void SetFlags( AEINT32 nMask );
	
	/// \brief
	///   Adds a specific bitflag (see constructor for supported bitflags)
	AE_FORCEINLINE void SetFlag( AEINT32 nMask );
	
	/// \brief
	///   Removes a specific bitflag (see constructor for supported bitflags)
	AE_FORCEINLINE void RemoveFlag( AEINT32 nMask );
	
	/// \brief
	///   Gets the bitflag mask (see constructor for supported bitflags)
	AE_FORCEINLINE AEINT32 GetFlags( void ) const;
	
	/// \brief
	///   Tests whether a specific flag is set (see constructor for supported bitflags)
	AE_FORCEINLINE AEBOOL32 IsFlagSet( AEINT32 nMask ) const;
	
	/// \brief
	///   Casts into a 32 bit integer
	AE_FORCEINLINE operator AEINT32 &();
	
	/// \brief
	///   Assignment operator
	AE_FORCEINLINE AEINT32 &operator = ( AEINT32 nOther );
	
	/// \brief
	///   Assignment operator
	AE_FORCEINLINE AEINT32 &operator = ( const AESimpleRenderState &refOther );
	
	/// \brief
	///   Comparison operator
	AE_FORCEINLINE AEBOOL32 operator == ( const AESimpleRenderState &refOther ) const;
	
	/// \brief
	///   Comparison operator
	AE_FORCEINLINE AEBOOL32 operator != ( const AESimpleRenderState &refOther ) const;
};

#include "AESimpleRenderState.inl"

#endif // _AESIMPLERENDERSTATE_H_
